package com.tyylab.kestrel.framework.core;

import com.alibaba.fastjson.JSONObject;
import com.tyylab.kestrel.framework.core.build.DefaultClassBuilder;
import com.tyylab.kestrel.framework.core.annoutil.SpringCoreAnnotationUtil;
import com.tyylab.kestrel.framework.core.build.ParamEntityClzGenerator;
import lombok.SneakyThrows;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.Argument;
import net.bytebuddy.implementation.bind.annotation.This;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * TEST
 */
public class App {
    public static void main(String[] args) {
        int i =0;
        Object arges = i;
        System.out.println(arges);
        System.out.println(arges.getClass().toString());
        printall(12,"2232",33.5);
    }

    public static void printall(Object ... args){
        if (null!= args && args.length > 0){

            for (Object arg : args){
                System.out.println(arg.getClass().toString());
            }
        }
    }
    @SneakyThrows
    public static void main1(String[] args) {
        DefaultClassBuilder builder = new DefaultClassBuilder();
        Class<?> clazz =
                builder.defineClass()
                        .clazz("com.tyylab.Test")
                        .annotate(SpringCoreAnnotationUtil.configuration("config"))
                        .modifiers(Modifier.PUBLIC)
                        .end()

                        .defineProperty()
                        .property("name",String.class,true)
                        .end()

                        .defineProperty()
                        .property("age",int.class,true)
                        .annotate(SpringCoreAnnotationUtil.autowired(true))
                        .end()

                        .defineMethod()
                        .method("test",String.class,Modifier.PUBLIC)
                        .param("input",String.class)
                        .end()
                        .impl()
                        .delegate(App.class)
                        .annotateMethod(SpringCoreAnnotationUtil.autowired(true))
                        .end()
                        .end()

                        .defineMethod()
                        .method("test2",String.class,Modifier.PUBLIC)
                        .param("input",String.class).end()
                        .param("age",Integer.class)
                        .end()
                        .impl()
                        .callOnField(null,null)
                        .annotateMethod(SpringCoreAnnotationUtil.autowired(true))
                        .end()
                        .end()
                        .build();
        System.out.println("success :" + clazz.getName());
        Object instance = clazz.getDeclaredConstructor().newInstance();
        Method method = clazz.getMethod("test",String.class);

        System.out.println(method.invoke(instance,"bill"));;
        System.out.println(instance.toString());

        Class  clz = new ParamEntityClzGenerator().generateMethodParamClass(method,clazz);
        Object obj = clz.getDeclaredConstructor().newInstance();
        Field field = obj.getClass().getDeclaredField("f_42c25be3a5db3f1f8377f4c2db62bfe9_0");
        field.setAccessible(true);
        field.set(obj,"bill");
        System.out.println(JSONObject.toJSONString(obj));
    }

    public static void main0(String[] args) {
        System.out.println(new App().getName());
    }

    @SneakyThrows
    public String getName() {
        Object instance =
        new ByteBuddy().subclass(Object.class).name("com.tyylab.Test")

                .defineMethod("test", String.class, Modifier.PUBLIC)
                .intercept(MethodDelegation.to(App.class))
                .make().load(this.getClass().getClassLoader()).getLoaded()

                .getDeclaredConstructor().newInstance();
        return instance.toString();
    }
        ;

    public static String test(@Argument(0) String input, // 获取字符串参数
                              @This Object instance  ){
        System.out.println(instance.toString());
        return "hello";
    }
}
